package com.im.service.user.smo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.im.service.dto.*;
import com.im.util.JsonUtil;
import com.im.util.ListUtil;
import com.im.util.StringUtil;
import com.sun.org.apache.xpath.internal.operations.Bool;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.im.service.user.dao.IStaffQueryDAO;
import com.im.service.user.dao.IUserQueryDAO;
import org.springframework.util.CollectionUtils;

@Service
public class UserQuerySMOImpl implements IUserQuerySMO{
	
	@Autowired
	private IUserQueryDAO userQueryDAO;
	@Autowired
	private IStaffQueryDAO staffQueryDAO;

	@Override
	public Map<String, Object> queryStaffBaseInfo(Map<String, Object> param) {
		
		Map<String, Object> resultMap = new HashMap<>();
		//查询员工基本信息
		if(param.containsKey("staff")){
			resultMap.put("staff", staffQueryDAO.queryStaff(param));
		}
		//查询员工对应的角色信息
		if(param.containsKey("staff2Roles")){
			resultMap.put("staff2Roles", staffQueryDAO.queryStaff2RoleByCond(param));
		}
		//查询员工对应的菜单权限
		if(param.containsKey("role2FuncMenus")){
			//查询工号角色
			List<Staff2Role> staff2Roles = staffQueryDAO.queryStaff2RoleByCond(param);
			if(staff2Roles != null && staff2Roles.size()  != 0){
				//查询角色菜单
				param.put("staff2Roles",staff2Roles);
				resultMap.put("role2FuncMenus", staffQueryDAO.queryRole2FuncMenuByCond(param));
			}else{
				resultMap.put("role2FuncMenus", "[]");
			}
		}
		//员工菜单
		if(param.containsKey("funcMenus")){
			//查询工号角色
			List<Staff2Role> staff2Roles = staffQueryDAO.queryStaff2RoleByCond(param);
			if(staff2Roles != null  && staff2Roles.size()  != 0){
				param.put("staff2Roles",staff2Roles);
				List<FuncMenu> funcMenus = staffQueryDAO.queryStaffFuncMenus(param);

				if(funcMenus != null){
					resultMap.put("funcMenus", insortFuncMenu(funcMenus));
				}else{
					resultMap.put("funcMenus", "[]");
				}
			}else{
				resultMap.put("funcMenus", "[]");
			}

		}
		//查询员工对应的数据维度
		if(param.containsKey("staff2RoleRanges")){
			
		}
		
		return resultMap;
	}

	@Override
	public List<FuncMenu> queryStaffFuncMenus(Map<String, Object> param) {
		//查询工号角色
		List<Staff2Role> staff2Roles = staffQueryDAO.queryStaff2RoleByCond(param);
		if (!CollectionUtils.isEmpty(staff2Roles)) {
			param.put("staff2Roles", staff2Roles);
			List<FuncMenu> funcMenus = staffQueryDAO.queryStaffFuncMenus(param);

			return insortFuncMenu(funcMenus);
		}
		return new ArrayList<>();
	}


	private List<FuncMenu> insortFuncMenu(List<FuncMenu> oriList){
		List<FuncMenu> newList = new ArrayList<>();
		//父
		for(FuncMenu funcMenu : oriList){
			if(funcMenu.getParentFuncMenuId() == null || "".equals(funcMenu.getParentFuncMenuId())){
				boolean ifExist = false;
				for(FuncMenu funcMenufa : newList){
					if(funcMenu.getFuncMenuId().equals(funcMenufa.getFuncMenuId())){
						//已存在
						ifExist = true;
						break;
					}
				}
				if(!ifExist){
					newList.add(funcMenu);
				}
			}

		}

		//子
		for(FuncMenu funcMenu : newList){

			List<FuncMenu>  childFuncs = funcMenu.getChildMenu();
			if(childFuncs == null){
				childFuncs = new ArrayList<>();
				funcMenu.setChildMenu(childFuncs);
			}

			for(FuncMenu funcMenuch : oriList){
				if(funcMenuch.getParentFuncMenuId() != null && funcMenuch.getParentFuncMenuId().equals(funcMenu.getFuncMenuId())){
					//是否存在
					boolean ifExist = false;
					for(FuncMenu func : childFuncs){
						if(func.getFuncMenuId().equals(funcMenu.getFuncMenuId())){
							break;
						}
					}

					if(!ifExist){
						childFuncs.add(funcMenuch);
					}
				}
			}

		}
		return newList;

	}

	@Override
	public PageQuery<Staff> queryStaffsByCond(Map<String, Object> param) {
		//不能为空
		if(param.containsKey("staffName") && "".equals(param.get("staffName").toString().trim())){
			param.remove("staffName");
		}
		//如果组织,引用递归查询所有组织节点
		List<String> parentOrgIds = new ArrayList<>();
		if(param.containsKey("orgId")){
			if("".equals(param.get("orgId").toString())){
				param.remove("orgId");
			}else{
				param.put("orgIds",queryAllChildren(param.get("orgId").toString(),parentOrgIds));
				param.remove("orgId");
			}
		}
		//设置分页
		PageQuery<Staff> page;
		if(param.containsKey("pageInfo")){
			page = JsonUtil.jsonToBean(param.get("pageInfo").toString(),PageQuery.class);
		}else{
			page = new PageQuery<>();
		}
		PageHelper.startPage(page.getPageNumber(), page.getPageSize());
		List<Staff> list= staffQueryDAO.queryStaffsByCond(param);
		page.setRows(list);
		page.setTotalPages(((Page<Staff>)list).getPages());
		page.setTotal(((Page<Staff>) list).getTotal());
		return page;
	}
	/*
	递归查询所有子节点
	 */
	public List<String> queryAllChildren(String orgId,List<String> retList){

		int count = 10;
		//根据oriList查询
		List<String> oriList = new ArrayList<>();
		oriList.add(orgId);
		while(oriList.size() > 0 && count > 0){
			//最多循环10次
			count --;
			retList.addAll(oriList);
			oriList  = queryChildren(oriList);
		}

		return retList;
	}
	private List<String> queryChildren(List<String> oriList){
		//根据oriList查询
		Map<String,Object> param = new HashMap<>();
		param.put("parentOrgIds",oriList);
		List<Orgarization> orgarizations = staffQueryDAO.queryOrgarizationsByCond(param);
		if(orgarizations != null){
			List<String> retList = new ArrayList<>();
			for(Orgarization orgarization : orgarizations){
				retList.add(orgarization.getOrgId());
			}
			return retList;
		}else{
			return new ArrayList<>();
		}
	}

	@Override
	public PageQuery<Role> queryConfigRolesByCond(Map<String, Object> param) {
		if(param.containsKey("roleName") && "".equals(param.get("roleName").toString().trim())){
			param.remove("roleName");
		}
		//设置分页
		PageQuery<Role> page;
		if(param.containsKey("pageInfo")){
			page = JsonUtil.jsonToBean(param.get("pageInfo").toString(),PageQuery.class);
		}else{
			page = new PageQuery<>();
		}
		//return staffQueryDAO.queryConfigRolesByCond(param);
        if(!param.containsKey("statusCd")){
            param.put("statusCd","10");
        }
		PageHelper.startPage(page.getPageNumber(), page.getPageSize());
		List<Role> list= staffQueryDAO.queryConfigRolesByCond(param);
		page.setRows(list);
		page.setTotalPages(((Page<Role>)list).getPages());
		page.setTotal(((Page<Role>) list).getTotal());
		return page;
	}

	@Override
	public List<StaffLimitType> queryConfigStaffLimitType(Map<String, Object> param) {
		param.put("statusCd" , "10");
		return staffQueryDAO.queryConfigStaffLimitType(param);
	}

	/**
	 * limitTypeId
	 * staffId  被操作的用户对象,为空时返回当前员工的数据维度
	 * loginedStaffId 登录的用户对象
	 * @param param
	 * @return
	 */
	@Override
	public Map<String,Object> queryLimitInstByConn(Map<String, Object> param) {
		Map<String,Object> resultMap = new HashMap<>();
		resultMap.put("resultCode","0");
		resultMap.put("resultMsg","查询成功");

		try{
			if(!param.containsKey("loginedStaffId")){
				resultMap.put("resultCode","-1");
				resultMap.put("resultMsg","员工未登录，无法操作数据维度！");
				return resultMap;
			}



			Map<String,Object> qparam = new HashMap<>();
			if(param.containsKey("staffId")){
				//如果包含被操作员工和登录员工
				String staffId = param.get("staffId").toString();
				String loginedStaffId = param.get("loginedStaffId").toString();
				List<String> staffIds = new ArrayList<>();
				staffIds.add(staffId);
				staffIds.add(loginedStaffId);

				qparam.put("staffIds",staffIds);
				qparam.put("limitTypeId","-9999");

				//判断是否包含通用数据维度
				List<StaffLimitRange> staffLimitRanges = staffQueryDAO.queryLimitInstByConn(qparam);
				boolean existsAllLimitLogined = false;//登录员工是否有通用数据维度权限
				boolean existsAllLimit = false;//操作用户是否有通用数据维度权限
				if(staffLimitRanges != null){
					for(StaffLimitRange staffLimitRange : staffLimitRanges){
						if(staffLimitRange.getStaffId().equals(staffId)){
							existsAllLimit = true;
							continue;
						}
						if(staffLimitRange.getStaffId().equals(loginedStaffId)){
							existsAllLimitLogined = true;
							continue;
						}
					}
				}

				if(existsAllLimit && existsAllLimitLogined){
					//如果二者都还有通用权限，可直接返回
					resultMap.put("ifHasAll","Y");
					resultMap.put("ifHasAllLogined","Y");
					resultMap.put("result","[]");
					return resultMap;
				}else if(!existsAllLimit && existsAllLimitLogined){
					//如果登录员工为通用权限，直接返回被操作用户的数组
					resultMap.put("ifHasAllLogined","Y");
					resultMap.put("ifHasAll","N");
					resultMap.put("result",staffQueryDAO.queryLimitInstByConn(param));
				}else if(existsAllLimit && !existsAllLimitLogined){
					//登录员工权限小于操作员工权限，直接返回报错！
					resultMap.put("resultCode","-1");
					resultMap.put("resultMsg","当前登录员工的数据维度权限小于被操作员工，无法操作！");
					return resultMap;
				}else{
					//二者都不为通用权限，取二者交集
					resultMap.put("ifHasAllLogined","N");
					resultMap.put("ifHasAll","N");

					staffLimitRanges = new ArrayList<>();
					//当前登录员工  和 操作用户的交集
					//当前登录员工的数据维度
					param.put("staffId",loginedStaffId);
					List<StaffLimitRange> staffLimitRangesForLogined = staffQueryDAO.queryLimitInstByConn(param);

					//当前被操作员工的数据维度
					param.put("staffId",staffId);
					List<StaffLimitRange> staffLimitRangesForUser = staffQueryDAO.queryLimitInstByConn(param);

					//交集
					for(StaffLimitRange staffLimitRange : staffLimitRangesForUser){

						for(StaffLimitRange staffLimitRange1 : staffLimitRangesForLogined){

							if(staffLimitRange.getLimitRangeId().equals(staffLimitRange1.getLimitRangeId())){
								staffLimitRanges.add(staffLimitRange);
								break;
							}

						}

					}
					resultMap.put("result",staffLimitRanges);

				}

			}else{
				//如果仅仅为登录员工
				qparam.put("staffId",param.get("loginedStaffId").toString());
				qparam.put("limitTypeId","-9999");

				List<StaffLimitRange> staffLimitRanges = staffQueryDAO.queryLimitInstByConn(qparam);
				//boolean existsAllLimitLogined = false;//登录员工是否有通用数据维度权限
				if(staffLimitRanges != null && staffLimitRanges.size() > 0){
					resultMap.put("ifHasAllLogined","Y");
					resultMap.put("ifHasAll","Y");
					resultMap.put("result","[]");
				}else{
					resultMap.put("ifHasAllLogined","N");
					resultMap.put("ifHasAll","N");
					param.put("staffId",param.get("loginedStaffId").toString());
					if(!param.containsKey("limitTypeId")){
						//不包含类型，直接告知是否有通用维度
						resultMap.put("result","[]");
					}else{
						resultMap.put("result",staffQueryDAO.queryLimitInstByConn(param));
					}
				}
			}

		}catch (Exception e){
			resultMap.put("resultCode","-1");
			resultMap.put("resultMsg","查询失败"+e.getMessage());
		}

		return resultMap;
	}

	@Override
	public List queryOrgarizationsByCond(Map<String, Object> param) {
	    if(!param.containsKey("statusCd")){
            param.put("statusCd",10);
        }
		if(param.containsKey("forOrgList")){
			if(param.containsKey("orgType") && "".equals(param.get("orgType").toString())){
				param.remove("orgType");
			}
			if(param.containsKey("orgName") && "".equals(param.get("orgName").toString())){
				param.remove("orgName");
			}
			if(param.containsKey("notOrgType") && "".equals(param.get("notOrgType").toString())){
				param.remove("notOrgType");
			}
			if(param.containsKey("orgId") && "".equals(param.get("orgId").toString())){
				param.remove("orgId");
			}
			//是否按照正常bean返回
			if(param.containsKey("orgId")){
				List<Orgarization> oriList = staffQueryDAO.queryOrgarizationsByCond(param);
				if(oriList == null || oriList.size() == 0){
					return new ArrayList();
				}
				param.remove("orgId");
				int count = 10;
				List<Orgarization> retList = new ArrayList<>();
				while(oriList != null && oriList.size() > 0 && count > 0){
					//最多循环10次
					count --;
					retList.addAll(oriList);
					//根据oriList查询
					param.put("parentOrgObjs",oriList);
					oriList = staffQueryDAO.queryOrgarizationsByCond(param);
				}

				return retList;
			}
			return  staffQueryDAO.queryOrgarizationsByCond(param);
		}else if(param.containsKey("hasOrgType")){
			//先查询组织类型
			List<EasyUiTreeDto> orgTypes = staffQueryDAO.queryOrgTypeByCond(param);
			Map<String,String> attributes = new HashMap<>();
			attributes.put("dataType","ORG_TYPE");
			for(EasyUiTreeDto easyUiTreeDto : orgTypes){
				//类型节点设置
				easyUiTreeDto.setAttributes(attributes);
			}
			return orgTypes;
		}else{
			//按照easyUi tree
			List<EasyUiTreeDto> orgs = staffQueryDAO.queryOrgTreeByCond(param);

			if(!param.containsKey("parentOrgId")){
				//是组织父节点，标注一下
				Map<String,String> attributes = new HashMap<>();
				attributes.put("dataType","PARENT_ORG");
				for(EasyUiTreeDto easyUiTreeDto : orgs){
					//类型节点设置
					easyUiTreeDto.setAttributes(attributes);
				}
			}
			return orgs;
		}
	}
    @Override
    public PageQuery<Orgarization> queryOrgarizationsByCondPage(Map<String, Object> param) {

        if(param.containsKey("orgType") && "".equals(param.get("orgType").toString())){
            param.remove("orgType");
        }
        if(param.containsKey("orgName") && "".equals(param.get("orgName").toString())){
            param.remove("orgName");
        }
        if(param.containsKey("orgId") && "".equals(param.get("orgId").toString())){
            param.remove("orgId");
        }
        if(!param.containsKey("statusCd")){
            param.put("statusCd",10);
        }
        //设置分页
        PageQuery<Orgarization> page;
        if(param.containsKey("pageInfo")){
            page = JsonUtil.jsonToBean(param.get("pageInfo").toString(),PageQuery.class);
        }else{
            page = new PageQuery<>();
        }
        PageHelper.startPage(page.getPageNumber(), page.getPageSize());
        List<Orgarization> list= staffQueryDAO.queryOrgarizationsByCond(param);
        page.setRows(list);
        page.setTotalPages(((Page<Orgarization>)list).getPages());
        page.setTotal(((Page<Orgarization>) list).getTotal());
        return page;
    }
	@Override
	public List queryFuncMenusByCond(Map<String, Object> param) {
		if(param.containsKey("roleId") && "".equals(param.get("roleId").toString().trim())){
			param.remove("roleId");
		}
		if(param.containsKey("forEasyUiTree")){
			//按easyui tree格式返回
			List<FuncMenu> oriList = insortFuncMenu(staffQueryDAO.queryFuncMenusByCond(param));

			//转换格式
			List retList = new ArrayList();
			for(FuncMenu parent : oriList){
				EasyUiTreeDto easyUiTreeDto = new EasyUiTreeDto();
				easyUiTreeDto.setId(parent.getFuncMenuId());
				easyUiTreeDto.setText(parent.getName());
				easyUiTreeDto.setState("open");
				List<FuncMenu> children = parent.getChildMenu();
				if(children != null && children.size() > 0 ){
					List<EasyUiTreeDto> leafs = new ArrayList<>();
					easyUiTreeDto.setState("open");
					for (FuncMenu child : children){
						EasyUiTreeDto easyUiTreeDtoChi = new EasyUiTreeDto();
						easyUiTreeDtoChi.setId(child.getFuncMenuId());
						easyUiTreeDtoChi.setText(child.getName());
						easyUiTreeDtoChi.setState("open");
						Map<String,String> attr = new HashMap();
						attr.put("parentFuncMenuId",parent.getFuncMenuId());
						easyUiTreeDtoChi.setAttributes(attr);
						leafs.add(easyUiTreeDtoChi);
					}
					easyUiTreeDto.setChildren(leafs);
				}
				retList.add(easyUiTreeDto);
			}
			return retList;
		}else{
			if(param.containsKey("noSort")){
				//不需要按层级
				return staffQueryDAO.queryFuncMenusByCond(param);

			}else{
				return insortFuncMenu(staffQueryDAO.queryFuncMenusByCond(param));
			}
		}
	}

	/**
	 * 入参是:limitTypeId,staffId,rangeValue(可空），chkType(1:查列表，2：查真假）
	 * @param str
	 * @return
	 */
	@Override
	public Map<String, Object> queryStaffRange(String str) {

        Map<String, Object> retMap = new HashMap<String, Object>();

		String errorMsg = "解析json参数时：";
		JSONObject jo = JSONObject.fromObject(str);

		String limitTypeId = JsonUtil.getNotNullStringFromJSON(jo, "limitTypeId", errorMsg);
		String staffId = JsonUtil.getNotNullStringFromJSON(jo, "staffId", errorMsg);
		String rangeValue = JsonUtil.getStringFromJSON(jo, "rangeValue", errorMsg);
		String chkType = JsonUtil.getNotNullStringFromJSON(jo, "chkType", errorMsg);

		if(!"1".equals(chkType) && !"2".equals(chkType)){
            retMap.put("ret","chkType未在定义范围");
            return  retMap;
        }
		Map<String,Object> inMap = new HashMap<String,Object>();
		inMap.put("limitTypeId",limitTypeId);
		inMap.put("staffId",staffId);
        if(!StringUtil.isEmpty(rangeValue)){
            inMap.put("rangeValue",rangeValue);
        }
        //this.queryConfigStaffLimitType(inMap);
		List<StaffLimitRange> staffLimitRanges = staffQueryDAO.queryLimitInstByConn(inMap);

		if("1".equals(chkType)){
            retMap.put("ret",staffLimitRanges);
        } else{
            retMap.put("ret",!ListUtil.isListEmpty(staffLimitRanges));
        }
		return  retMap;
	}
}
